
#include <BOpenGL>

#include "member_BProgram.h"

using namespace BWE;

member_BProgram::member_BProgram(BProgram* boss)
{
	program = boss;
	object = 0;
	dirty = false;
}
member_BProgram::~member_BProgram()
{

}

bool member_BProgram::use()
{
	if (dirty)
	{
		if (!object)
			object = glCreateProgram();
		if (!object)
			return false;
		for (auto it = shaders.begin(); it != shaders.end(); ++it)
		{
			BShader* shader = *it;
			if (!shader_member(shader)->compile())
				return false;
		}
		for (auto it = shaders.begin(); it != shaders.end(); ++it)
		{
			BShader* shader = *it;
			GLuint sobj = shader_member(shader)->object;
			glAttachShader(object, sobj);
			if (!BOpenGL::Check())
				return false;
		}
		glLinkProgram(object);
		if (!BOpenGL::Check())
			return false;
		dirty = false;
	}

	if (!object)
		return false;

	glUseProgram(object);
	if (!BOpenGL::Check())
		return false;
	for (int i = 0; i < uniforms.size(); i++)
	{
		BUniform* uniform = uniforms[i];
		if (uniform_member(uniform)->location < 0)
		{
			uniform_member(uniform)->location = glGetUniformLocation(object, uniform->sign().cstr());
		}
		if (uniform_member(uniform)->location >= 0 && uniform_member(uniform)->dirty)
		{
			uniform_member(uniform)->fresh(object);
		}
	}
	return true;
}
